#include "myApplication.h"
//


//-------------------------------------------------------------------------------------
myApplication::myApplication()
    : playerPlane(0),playerNode(0),primCamNode(0), secCamNode(0)
{
}
//-------------------------------------------------------------------------------------
myApplication::~myApplication()
{
	
}  

void myApplication::initTitleScreen()
{
	introSceneCam = introSceneMgr->getCamera("introCam");
	introOverlayMgr = Ogre::OverlayManager::getSingletonPtr();
	
	Ogre::Overlay* titleOverlay = introOverlayMgr->create("TitleScreenOverlay");
	Ogre::OverlayElement* title_screen_elem = Ogre::OverlayManager::getSingleton().getOverlayElement("goKartMedia/title");
	Ogre::OverlayElement* selector_elem = Ogre::OverlayManager::getSingleton().getOverlayElement("goKartMedia/selector");
	Ogre::OverlayContainer* titlePanel = static_cast<Ogre::OverlayContainer*>(introOverlayMgr->createOverlayElement("Panel", "titlePanel"));

	selector_elem->setHorizontalAlignment(Ogre::GHA_CENTER);
	selector_elem->setVerticalAlignment(Ogre::GVA_CENTER);
	selector_elem->setLeft(-100);
	titlePanel->addChild(title_screen_elem);
	titlePanel->addChild(selector_elem);
	titleOverlay->add2D(titlePanel);
	titleOverlay->show();
}

static void checkJulianDay(double jd,
                int year, int month, int day,
                int hour, int minute, caelum::LongReal second)
        {
            int cyear, cmonth, cday, chour, cminute;
            caelum::LongReal calcJd;
            int calcIjd;
            caelum::LongReal csecond;
            
            // Round-trip integer julian day.
            calcIjd = caelum::Astronomy::getJulianDayFromGregorianDate(year, month, day);
            caelum::Astronomy::getGregorianDateFromJulianDay(calcIjd, cyear, cmonth, cday);
            assert(cyear == year);
            assert(cmonth == month);
            assert(cday == day);

            // Check floating-point julian day.
            calcJd = caelum::Astronomy::getJulianDayFromGregorianDateTime
                    (year, month, day, hour, minute, second);
            assert(Ogre::Math::RealEqual(jd, calcJd));

            caelum::Astronomy::getGregorianDateTimeFromJulianDay(calcJd,
                    cyear, cmonth, cday, chour, cminute, csecond);
            assert(cyear == year);
            assert(cmonth == month);
            assert(cday == day);
            assert(chour == hour);
            assert(cminute == minute);
            // We can lose a lot of precision.
            assert(Ogre::Math::RealEqual(csecond, second, 0.1));
        }

        static void checkSunPosition(
                caelum::LongReal jday,
                Ogre::Degree longitude, Ogre::Degree latitude,
                Ogre::Degree azimuth, Ogre::Degree altitude)
        {
            Ogre::Degree cazimuth, caltitude;
            caelum::Astronomy::getHorizontalSunPosition(
                    jday, longitude, latitude, cazimuth, caltitude);
            // Allow for large errors.
            assert(Ogre::Math::RealEqual(cazimuth.valueDegrees(), azimuth.valueDegrees(), 0.3));
            assert(Ogre::Math::RealEqual(caltitude.valueDegrees(), altitude.valueDegrees(), 0.3));
        }
        static void checkSunPosition(
                int year, int month, int day,
                int hour, int minute, caelum::LongReal second,
                Ogre::Degree longitude, Ogre::Degree latitude,
                Ogre::Degree azimuth, Ogre::Degree altitude)
        {
            caelum::LongReal jday = caelum::Astronomy::getJulianDayFromGregorianDateTime
                    (year, month, day, hour, minute, second);
            checkSunPosition(jday, longitude, latitude, azimuth, altitude);
        }

        void checkAstronomy() {
            // Tested with http://aa.usno.navy.mil/data/docs/JulianDate.php
            checkJulianDay(2451545.0, 2000, 1, 1, 12, 0, 0);
            checkJulianDay(2452986.01094, 2003, 12, 12, 12, 15, 45);
            //The Julian date for CE 1976 February 24 01:10:55.0 UT is JD 2442832.54925
            checkJulianDay(2442832.54925, 1976,  2, 24,  1, 10, 55);
            //The Julian date for CE 1845 November 11 07:03:20.0 UT is JD 2395246.79398
            checkJulianDay(2395246.79398, 1845, 11, 11,  7,  3, 20);
            //The Julian date for CE  2067 April  1 23:59:59.0 UT is JD 2476107.49999
            checkJulianDay(2476107.49999, 2067,  4,  1, 23, 29, 59);

            // Various javascript calculators on the web.
            checkSunPosition(2448000.5, Degree(15), Degree(60), Degree(15.6767), Degree(-17.9570));
            checkSunPosition(2442832.54925, Degree(-15), Degree(3), Degree(185.1), Degree(-83.1));
            checkSunPosition(2008, 1, 4, 14, 46, 17,
                    Degree(-82.63), Degree(27.97), Degree(136.8552), Degree(24.936968432703356));
            checkSunPosition(2000, 12, 3, 12, 34, 0,
                    Degree(-81.70), Degree(41.00), Degree(118.93), Degree(-0.84));
        }
//-------------------------------------------------------------------------------------

bool myApplication::collision(OgreOde::Contact* Contact)
{

		Contact->setCoulombFriction(35.0);//OgreOde::Utility::Infinity);

		 return true;
}

void myApplication:: initSpotLights(void)
{
	
	Ogre::String s; 
	Ogre::String s2; 
	Ogre::String s3; 
	   for(int i=0; i<23;i++)
	   {
		 s=  "lampE"+Ogre::StringConverter::toString(i);
		 s2="lampN"+Ogre::StringConverter::toString(i);
		 s3="floodlight"+Ogre::StringConverter::toString(i);
		  
		   lampEnt[i]=primarySceneMgr->createEntity(s,"Light_post.mesh");
		   lampNode[i]=primarySceneMgr->getRootSceneNode()->createChildSceneNode( s2 );
		   lightArr[i]=primarySceneMgr->createLight(s3);
	   }

}

void myApplication::createSpotLights(int index,Vector3 nodePos,Vector3 pos,Radian pitch,Radian roll)
{	lampNode[index]->attachObject( lampEnt[index] );
	    lampNode[index]->setPosition(nodePos);
	    lampNode[index]->pitch( Degree( pitch ) );
	   lampNode[index]->roll( Degree( roll) );
	  lampNode[index]->scale(0.2,0.2,0.2);
	lightArr[index]->setPosition(pos);
	lightArr[index]->setType(Light::LT_SPOTLIGHT);
		lightArr[index]->setDirection(Vector3(0,-1,0));
		 lightArr[index]->setDiffuseColour(ColourValue(1, 1, 1));
       lightArr[index]->setSpecularColour(ColourValue(1,1  , 1));
	    lightArr[index]->setSpotlightRange(Degree(35), Degree(100),0.0001);//works

		lightArr[index]->setVisible(true);
}
void myApplication::initRamps(void)
{
	Ogre::String rampEntName;
	Ogre::String rampNodeName;
	for(int i = 0; i < 5; i++)
	{
		rampEntName = "rampEnt_"+Ogre::StringConverter::toString(i);
		rampNodeName = "rampNode_"+Ogre::StringConverter::toString(i);
		rampEnt[i] = primarySceneMgr->createEntity(rampEntName, "crate.mesh");
		rampEnt[i]->setNormaliseNormals(true);
		rampNode[i] = primarySceneMgr->getRootSceneNode()->createChildSceneNode( rampNodeName );
	}

}
void myApplication::createRamps(int index, Vector3 nodePos, Degree facing)
{
	rampNode[index]->attachObject( rampEnt[index] );
	rampNode[index]->setPosition( nodePos );
	rampNode[index]->yaw( Radian( facing ) );
	rampNode[index]->pitch( Radian(0.4) );
	rampNode[index]->setScale(0.3,0.1,0.4);

	OgreOde::EntityInformer ei(rampEnt[index], Matrix4::getScale(rampNode[index]->getScale()));
	OgreOde::Geometry *geom = ei.createSingleStaticBox(mWorld, mSpace);
	rampEnt[index]->setUserObject(geom);
}

	
void myApplication::createScene()
{
	
	overlayMgr = Ogre::OverlayManager::getSingletonPtr(); 

	VPOL = new viewPortOverlayListener(mWindow, overlayMgr);
	mWindow->addListener(VPOL);

//*************************************************************************************TEST 
	primSceneCam = primarySceneMgr->getCamera(PLAYER_1_CAM);
	primSceneCam->setPosition(Vector3(125,-14,8));
    primSceneCam->lookAt(primSceneCam->getPosition() + Ogre::Vector3(0,0,1));
    primSceneCam->setNearClipDistance( 1 );
    primSceneCam->setFarClipDistance( 800 );

	secSceneCam = primarySceneMgr->getCamera(PLAYER_2_CAM);
	secSceneCam->setPosition(Vector3(125,-14,8));
    secSceneCam->lookAt(secSceneCam->getPosition() + Ogre::Vector3(0,0,1));
    secSceneCam->setNearClipDistance( 1 );
    secSceneCam->setFarClipDistance( 800 );

	playerPlane = primarySceneMgr->createEntity("playerPlane", "Kart.mesh");
	Track = primarySceneMgr->createEntity("track", "racingcircuit.mesh");

	trackNode = primarySceneMgr->getRootSceneNode()->createChildSceneNode();
	trackNode->attachObject(Track);
	

	playerNode = primarySceneMgr->getRootSceneNode()->createChildSceneNode();

	soundManager = new OgreAL::SoundManager();
	sound = soundManager->createSound("sound1", "fullspeed.wav", true, false);
	startGameSound = soundManager->createSound("startGameSound", "startGame.wav", false, false);
	cursorMove = soundManager->createSound("cursorMove", "moveCursor.ogg", false, false);
	introMusic = soundManager->createSound("introMusic", "introMusic.ogg", false, false);
	inGameMusic1 = soundManager->createSound("inGameMusic1", "move_and_proceed.ogg", true, false);
	
	caelum::CaelumSystem::CaelumComponent componentMask = 
                    static_cast<caelum::CaelumSystem::CaelumComponent> (
                    caelum::CaelumSystem::CAELUM_COMPONENT_SKY_COLOUR_MODEL |
                    caelum::CaelumSystem::CAELUM_COMPONENT_SUN |
                    caelum::CaelumSystem::CAELUM_COMPONENT_SOLAR_SYSTEM_MODEL |
                    caelum::CaelumSystem::CAELUM_COMPONENT_SKY_DOME |
                    caelum::CaelumSystem::CAELUM_COMPONENT_STARFIELD |
                    caelum::CaelumSystem::CAELUM_COMPONENT_CLOUDS |
                    caelum::CaelumSystem::CAELUM_COMPONENT_GROUND_FOG |
                    0);

	mCaelumSystem = new caelum::CaelumSystem (mRoot, primarySceneMgr, componentMask);
    mCaelumSystem->setManageSceneFog(true);
//    mCaelumSystem->setSceneFogDensityMultiplier(0.00000000015);
	mCaelumSystem->setSceneFogDensityMultiplier(0.015);
    if (mCaelumSystem->getSun ()) {
	   mCaelumSystem->getSun ()->setAmbientMultiplier (Ogre::ColourValue(0.8, 0.8, 0.8));
	   mCaelumSystem->getSun ()->setDiffuseMultiplier (Ogre::ColourValue(3, 3, 2.7));
	   // For green terrain:
	  // mCaelumSystem->getSun ()->setDiffuseMultiplier (Ogre::ColourValue(0.1, 3, 0.1));
	   mCaelumSystem->getSun ()->setSpecularMultiplier (Ogre::ColourValue(5, 5, 5));
	   mCaelumSystem->getSun ()->setManageAmbientLight (true);
	}
	if (mCaelumSystem->getGroundFog()) {
         mCaelumSystem->getGroundFog()->findFogPassesByName();
    }
    // Setup cloud options.
    // Tweak these settings to make the demo look pretty.
    if (mCaelumSystem->getClouds ()) {
       mCaelumSystem->getClouds ()->setCloudSpeed(Ogre::Vector2(0.000005, -0.000009));
       mCaelumSystem->getClouds ()->setCloudBlendTime(3600 * 24);
       mCaelumSystem->getClouds ()->setCloudCover(0.4);
	 
        }

		// Setup starfield options
    if (mCaelumSystem->getStarfield ()) {
		 mCaelumSystem->getStarfield ()->setInclination (Degree (13));
        }

	// Set time acceleration.
	mCaelumSystem->getUniversalClock ()->setTimeScale (1000);
    
	// Winter dawn in the southern hemisphere, looking north
	mCaelumSystem->getUniversalClock ()->setGregorianDateTime (2008, 7, 4, 20, 33, 0);
    mCaelumSystem->getSolarSystemModel ()->setObserverLongitude (Ogre::Degree(151 + 12.0 / 60));

   // Sidney
   mCaelumSystem->getSolarSystemModel ()->setObserverLatitude (Ogre::Degree(-33 + 52.0 / 60));
    // Beyond the southern polar circle, no sunrise
    //mCaelumSystem->getSolarSystemModel ()->setObserverLatitude (Ogre::Degree(-70));
    // Beyond the northern polar circle, no sunset
    //mCaelumSystem->getSolarSystemModel ()->setObserverLatitude (Ogre::Degree(70));

	// Register caelum to the render target
	mWindow->addListener (mCaelumSystem);



	// Set ambient light
	primarySceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5));
	introSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5));



///////////////////////////////////////////////////OGre Ode//////////////////////
	mWorld = new OgreOde::World(primarySceneMgr);	
    mWorld->setGravity(Vector3(0,-9.80665,0));
    mWorld->setCFM(10e-5);
    mWorld->setERP(0.8);
    mWorld->setAutoSleep(false);
	//mWorld->setAutoSleepAverageSamplesCount(10);
    mWorld->setContactCorrectionVelocity(1.0);

	mWorld->setCollisionListener(this);

	mSpace = mWorld->getDefaultSpace();
	mSpace->setInternalCollisions(true);

	dotLoader = new OgreOde_Loader::DotLoader(mWorld);
	

	////////////////////////////Setup Vehicles and Obstacle////////////////////////////////////

	goKart = static_cast <OgreOde_Prefab::Vehicle *> (dotLoader->loadObject("goKart.ogreode", "goKart"));
	goKart2 = static_cast <OgreOde_Prefab::Vehicle *> (dotLoader->loadObject("goKartRed.ogreode", "goKartRed"));
	Obstacle1 = static_cast <OgreOde_Prefab::Vehicle *> (dotLoader->loadObject("jeep.ogreode", "JeepSway"));
	Obstacle2 = static_cast <OgreOde_Prefab::Vehicle *> (dotLoader->loadObject("jeep.ogreode", "JeepSway"));
	Obstacle3 = static_cast <OgreOde_Prefab::Vehicle *> (dotLoader->loadObject("jeep.ogreode", "JeepSway"));
	Obstacle4 = static_cast <OgreOde_Prefab::Vehicle *> (dotLoader->loadObject("jeep.ogreode", "JeepSway"));
	Obstacle5 = static_cast <OgreOde_Prefab::Vehicle *> (dotLoader->loadObject("jeep.ogreode", "JeepSway"));

	///////Player 1
	goKart->applyAntiSwayBarForces();
	goKart->enableAntiSway(true);
	goKart->setPosition(Vector3(0,100,0));

	////////Player2
	goKart2->applyAntiSwayBarForces();
	goKart2->enableAntiSway(true);;

	primSceneCam->setPosition(Vector3(100,200,100));

	trackNode->setPosition(Vector3(goKart->getPosition().x+130, goKart->getPosition().y+14, goKart->getPosition().z+100));
	///Re-adjust Player1 to track
	goKart->setPosition(Vector3(254.874,99.3631,123.066));

	////////Player2
	goKart2->applyAntiSwayBarForces();
	goKart2->enableAntiSway(true);
	goKart2->setPosition(Vector3(250.874,99.3631,123.066));

	//Jeep Obstacle 1
	Obstacle1->setPosition(Vector3(282.5,100.853,353.979));

	//Jeep Obstacle 2
	Obstacle2->setPosition(Vector3(160.111,99.3165,323.591));

	//Jeep Obstacle 3
	Obstacle3->setPosition(Vector3(9.576,99.659,2.96));

	//Jeep Obstacle 4
	Obstacle4->setPosition(Vector3(156.179,99.3212,-89.18122));
	
	//Jeep Obstacle 5
	Obstacle5->setPosition(Vector3(278.86,101.045,-73.7246));


	//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	///////////////////////////////////////////////////////////////////////////////////////////////////////////////

	goKart->getEntity()->setNormaliseNormals(true);
	goKart2->getEntity()->setNormaliseNormals(true);



	goKart->getWheel(0)->getEntity()->setNormaliseNormals(true);
	goKart->getWheel(1)->getEntity()->setNormaliseNormals(true);
	goKart->getWheel(2)->getEntity()->setNormaliseNormals(true);
	goKart->getWheel(3)->getEntity()->setNormaliseNormals(true);

	goKart->getWheel(0)->setPowerFactor(1);
	goKart->getWheel(1)->setPowerFactor(1);
	goKart->getWheel(2)->setPowerFactor(1);
	goKart->getWheel(3)->setPowerFactor(1);

    goKart2->getWheel(0)->getEntity()->setNormaliseNormals(true);
	goKart2->getWheel(1)->getEntity()->setNormaliseNormals(true);
	goKart2->getWheel(2)->getEntity()->setNormaliseNormals(true);
	goKart2->getWheel(3)->getEntity()->setNormaliseNormals(true);

	goKart2->getWheel(0)->setPowerFactor(1);
	goKart2->getWheel(1)->setPowerFactor(1);
	goKart2->getWheel(2)->setPowerFactor(1);
	goKart2->getWheel(3)->setPowerFactor(1);

	goKart->getSceneNode()->attachObject(sound);
	sound->setGain(0.1);
	sound->setPitch(0.1);






	const Ogre::Real _time_step = 0.01;
	const Ogre::Real time_scale = Ogre::Real(1.7);
	const Ogre::Real max_frame_time = Ogre::Real(1.0/4);
	const Ogre::Real frame_rate = Ogre::Real(1.0 / 60);
	mStepper = new OgreOde::ForwardFixedInterpolatedStepHandler(mWorld, OgreOde::StepHandler::QuickStep,
										_time_step,frame_rate, max_frame_time,time_scale);

	OgreOde::EntityInformer ei(Track, trackNode->_getFullTransform());
	mTrack = ei.createStaticTriangleMesh(mWorld, mSpace);
	Track->setUserObject(mTrack);
	

		

	    Ogre::Overlay* timeroverlay = overlayMgr->create("Timer"); 
		Ogre::Overlay* speedOverlay = overlayMgr->create("Speed");
		Ogre::Overlay* speedBarOverlay = overlayMgr->create("SpeedBar");

		Ogre::OverlayElement* timerBackground = Ogre::OverlayManager::getSingleton().getOverlayElement("goKartMedia/leftOverlay");
		Ogre::OverlayElement* right_timerBackground = Ogre::OverlayManager::getSingleton().getOverlayElement("goKartMedia/rightOverlay");
		Ogre::OverlayElement* speedContBackground = Ogre::OverlayManager::getSingleton().getOverlayElement("goKartMedia/speedContOverlay");
		Ogre::OverlayElement* r_speedContBackground = Ogre::OverlayManager::getSingleton().getOverlayElement("goKartMedia/leftScreenspeedContOverlay");
		Ogre::OverlayElement* l_speedContBackground = Ogre::OverlayManager::getSingleton().getOverlayElement("goKartMedia/rightScreenspeedContOverlay");
		Ogre::OverlayElement* speedBarBackground = Ogre::OverlayManager::getSingleton().getOverlayElement("goKartMedia/speedBarOverlay");
		Ogre::OverlayElement* l_speedBarBackground = Ogre::OverlayManager::getSingleton().getOverlayElement("goKartMedia/leftScreenspeedBarOverlay");
		Ogre::OverlayElement* r_speedBarBackground = Ogre::OverlayManager::getSingleton().getOverlayElement("goKartMedia/rightScreenspeedBarOverlay");
		Ogre::OverlayElement* blueHelmet = Ogre::OverlayManager::getSingleton().getOverlayElement("goKartMedia/helmet_blue");
		Ogre::OverlayElement* redHelmet = Ogre::OverlayManager::getSingleton().getOverlayElement("goKartMedia/helmet_red");
		Ogre::OverlayElement* positionBar = Ogre::OverlayManager::getSingleton().getOverlayElement("goKartMedia/posBar");

		//////////////////////////////Initialise all the Text Areas//////////////////////////////
        Ogre::TextAreaOverlayElement* textArea = static_cast<Ogre::TextAreaOverlayElement*>(overlayMgr->createOverlayElement("TextArea", "currentLap")); 
		Ogre::TextAreaOverlayElement* textArea1 = static_cast<Ogre::TextAreaOverlayElement*>(overlayMgr->createOverlayElement("TextArea", "Lap1")); 
	    Ogre::TextAreaOverlayElement* textArea2 = static_cast<Ogre::TextAreaOverlayElement*>(overlayMgr->createOverlayElement("TextArea", "Lap2")); 
	    Ogre::TextAreaOverlayElement* textArea3 = static_cast<Ogre::TextAreaOverlayElement*>(overlayMgr->createOverlayElement("TextArea", "Lap3")); 

		Ogre::TextAreaOverlayElement* r_textArea = static_cast<Ogre::TextAreaOverlayElement*>(overlayMgr->createOverlayElement("TextArea", "r_currentLap"));
		Ogre::TextAreaOverlayElement* r_textArea1 = static_cast<Ogre::TextAreaOverlayElement*>(overlayMgr->createOverlayElement("TextArea", "r_Lap1"));
		Ogre::TextAreaOverlayElement* r_textArea2 = static_cast<Ogre::TextAreaOverlayElement*>(overlayMgr->createOverlayElement("TextArea", "r_Lap2"));
		Ogre::TextAreaOverlayElement* r_textArea3 = static_cast<Ogre::TextAreaOverlayElement*>(overlayMgr->createOverlayElement("TextArea", "r_Lap3"));
		//////////////////////////////////////////////////////////////////////////////////////////////
		
/////////////////////////////////////////////Current Lap///////////////////////////////////////LEFT SIDE
        textArea->setMetricsMode(Ogre::GMM_PIXELS); 
        textArea->setPosition(140, 48); 
        textArea->setDimensions(100, 30); 
        textArea->setCharHeight(30); 
		textArea->setColourTop(Ogre::ColourValue(0,1,1));
		textArea->setColourBottom(Ogre::ColourValue(1,1,1));
        textArea->setFontName("LCD"); 
/////////////////////////////////////////////Lap1///////////////////////////////////////
		textArea1->setMetricsMode(Ogre::GMM_PIXELS); 
        textArea1->setPosition(70, 125); 
        textArea1->setDimensions(100, 30); 
        textArea1->setCharHeight(25); 
		textArea1->setColourTop(Ogre::ColourValue(0,1,1));
		textArea1->setColourBottom(Ogre::ColourValue(1,1,1));
        textArea1->setFontName("LCD"); 
/////////////////////////////////////////////Lap2///////////////////////////////////////
	    textArea2->setMetricsMode(Ogre::GMM_PIXELS); 
        textArea2->setPosition(70, 195); 
        textArea2->setDimensions(100, 30); 
        textArea2->setCharHeight(25); 
		textArea2->setColourTop(Ogre::ColourValue(0,1,1));
		textArea2->setColourBottom(Ogre::ColourValue(1,1,1));
        textArea2->setFontName("LCD"); 
/////////////////////////////////////////////Lap3///////////////////////////////////////
		textArea3->setMetricsMode(Ogre::GMM_PIXELS); 
        textArea3->setPosition(70, 265); 
        textArea3->setDimensions(100, 30); 
        textArea3->setCharHeight(25); 
		textArea3->setColourTop(Ogre::ColourValue(0,1,1));
		textArea3->setColourBottom(Ogre::ColourValue(1,1,1));
        textArea3->setFontName("LCD"); 

/////////////////////////////////////////////Current Lap///////////////////////////////////////RIGHT SIDE
        r_textArea->setMetricsMode(Ogre::GMM_PIXELS); 
        r_textArea->setPosition(650+850, 48); 
        r_textArea->setDimensions(100, 30); 
        r_textArea->setCharHeight(30); 
		r_textArea->setColourTop(Ogre::ColourValue(0,1,1));
		r_textArea->setColourBottom(Ogre::ColourValue(1,1,1));
        r_textArea->setFontName("LCD"); 
/////////////////////////////////////////////Lap1///////////////////////////////////////
		r_textArea1->setMetricsMode(Ogre::GMM_PIXELS); 
        r_textArea1->setPosition(690+850, 125); 
        r_textArea1->setDimensions(100, 30); 
        r_textArea1->setCharHeight(25); 
		r_textArea1->setColourTop(Ogre::ColourValue(0,1,1));
		r_textArea1->setColourBottom(Ogre::ColourValue(1,1,1));
        r_textArea1->setFontName("LCD"); 
/////////////////////////////////////////////Lap2///////////////////////////////////////
	    r_textArea2->setMetricsMode(Ogre::GMM_PIXELS); 
        r_textArea2->setPosition(690+850, 195); 
        r_textArea2->setDimensions(100, 30); 
        r_textArea2->setCharHeight(25); 
		r_textArea2->setColourTop(Ogre::ColourValue(0,1,1));
		r_textArea2->setColourBottom(Ogre::ColourValue(1,1,1));
        r_textArea2->setFontName("LCD"); 
/////////////////////////////////////////////Lap3///////////////////////////////////////
		r_textArea3->setMetricsMode(Ogre::GMM_PIXELS); 
        r_textArea3->setPosition(690+850, 265); 
        r_textArea3->setDimensions(100, 30); 
        r_textArea3->setCharHeight(25); 
		r_textArea3->setColourTop(Ogre::ColourValue(0,1,1));
		r_textArea3->setColourBottom(Ogre::ColourValue(1,1,1));
        r_textArea3->setFontName("LCD"); 

		Ogre::OverlayContainer* posBarPanel = static_cast<Ogre::OverlayContainer*>(overlayMgr->createOverlayElement("Panel", "positionBarPanel"));

		posBarPanel->addChild(blueHelmet);
		posBarPanel->addChild(redHelmet);
		posBarPanel->addChild(positionBar);
		
		Ogre::OverlayContainer* timerPanel = static_cast<Ogre::OverlayContainer*>(overlayMgr->createOverlayElement("Panel", "TimerPanel")); 

		
		timerPanel->addChild(timerBackground);
		timerPanel->addChild(textArea);
		timerPanel->addChild(textArea1);
		timerPanel->addChild(textArea2);
		timerPanel->addChild(textArea3);

		Ogre::OverlayContainer* right_timerPanel = static_cast<Ogre::OverlayContainer*>(overlayMgr->createOverlayElement("Panel", "rightTimerPanel"));
		
		right_timerPanel->addChild(right_timerBackground);
		right_timerPanel->addChild(r_textArea);
		right_timerPanel->addChild(r_textArea1);
		right_timerPanel->addChild(r_textArea2);
		right_timerPanel->addChild(r_textArea3);

		timeroverlay->add2D(timerPanel); 
		timeroverlay->add2D(right_timerPanel);
		timeroverlay->add2D(posBarPanel);
		timeroverlay->setZOrder(1);
		timeroverlay->show();
		
		Ogre::OverlayContainer* speedPanel = static_cast<Ogre::OverlayContainer*>(overlayMgr->createOverlayElement("Panel", "SpeedPanel"));	
			speedPanel->addChild(speedContBackground);

		Ogre::OverlayContainer* l_speedPanel = static_cast<Ogre::OverlayContainer*>(overlayMgr->createOverlayElement("Panel", "l_SpeedPanel"));	
			l_speedPanel->addChild(l_speedContBackground);

		Ogre::OverlayContainer* r_speedPanel = static_cast<Ogre::OverlayContainer*>(overlayMgr->createOverlayElement("Panel", "r_SpeedPanel"));	
			r_speedPanel->addChild(r_speedContBackground);

		speedOverlay->add2D(speedPanel);
		speedOverlay->add2D(l_speedPanel);
		speedOverlay->add2D(r_speedPanel);
		speedOverlay->setZOrder(2);
		speedOverlay->show();

		Ogre::OverlayContainer* speedBarPanel = static_cast<Ogre::OverlayContainer*>(overlayMgr->createOverlayElement("Panel", "SpeedBarPanel"));
			speedBarPanel->addChild(speedBarBackground);

		Ogre::OverlayContainer* l_speedBarPanel = static_cast<Ogre::OverlayContainer*>(overlayMgr->createOverlayElement("Panel", "l_SpeedBarPanel"));
			l_speedBarPanel->addChild(l_speedBarBackground);
		Ogre::OverlayContainer* r_speedBarPanel = static_cast<Ogre::OverlayContainer*>(overlayMgr->createOverlayElement("Panel", "r_SpeedBarPanel"));
			r_speedBarPanel->addChild(r_speedBarBackground);

		speedBarOverlay->add2D(speedBarPanel);
		speedBarOverlay->add2D(l_speedBarPanel);
		speedBarOverlay->add2D(r_speedBarPanel);
		speedBarOverlay->setZOrder(0);
		speedBarOverlay->show();
	

		initSpotLights();
		createSpotLights(0,Vector3(-30,98,0),Vector3(-30,130,0),Degree(270),Degree(270));
		createSpotLights(1,Vector3(100,98,-90),Vector3(100,112,-90),Degree(270),Degree(180));
		createSpotLights(2,Vector3(200,98,-90),Vector3(180,130,-90),Degree(270),Degree(90));
		createSpotLights(3,Vector3(240,98,-145),Vector3(240,130,-145),Degree(270),Degree(0));
		createSpotLights(4,Vector3(320,98,-90),Vector3(315,130,-90),Degree(270),Degree(90));
		createSpotLights(5,Vector3(270,98,-5),Vector3(260,120,-5),Degree(270),Degree(90));
		createSpotLights(6,Vector3(270,98.5,120),Vector3(260,120,120),Degree(270),Degree(90));
		createSpotLights(7,Vector3(270,98,250),Vector3(260,120,250),Degree(270),Degree(90));
		createSpotLights(8,Vector3(260,98,350),Vector3(265,120,350),Degree(270),Degree(210));
		createSpotLights(9,Vector3(190,98,350),Vector3(220,130,350),Degree(270),Degree(270));
		createSpotLights(10,Vector3(140,98,350),Vector3(140,130,350),Degree(270),Degree(270));
		createSpotLights(11,Vector3(180,98,250),Vector3(180,130,250),Degree(270),Degree(180));
		createSpotLights(12,Vector3(30,99,150),Vector3(30,130,150),Degree(270),Degree(270));
		createSpotLights(13,Vector3(50,98,270),Vector3(50,130,270),Degree(270),Degree(270));
		createSpotLights(14,Vector3(75,98,350),Vector3(80,130,350),Degree(270),Degree(270));
		createSpotLights(15,Vector3(253,100,320),Vector3(253,130,315),Degree(270),Degree(270));
		createSpotLights(16,Vector3(40,98,-82),Vector3(50,130,-80),Degree(270),Degree(200));
		createSpotLights(17,Vector3(150,98,-95),Vector3(171,130,-95),Degree(270),Degree(180));
		createSpotLights(18,Vector3(212,100,390),Vector3(212,130,390),Degree(270),Degree(0));
		createSpotLights(19,Vector3(128,101,408),Vector3(128,130,408),Degree(270),Degree(0));
		createSpotLights(20,Vector3(60,98,228),Vector3(65,130,228),Degree(270),Degree(270));
		createSpotLights(21,Vector3(-10,98,65),Vector3(-10,130,65),Degree(270),Degree(270));
		createSpotLights(22,Vector3(290,98,-176),Vector3(286,130,-176),Degree(270),Degree(90));

		//////////////////////Setup Ramps/////////////////////////////////////////////////////////

		initRamps();
		createRamps(0, Vector3(255,99,222), Degree(180));
		createRamps(1, Vector3(156,99,327), Degree(180));
		createRamps(2, Vector3(85,98,320), Degree(0));
		createRamps(3, Vector3(40,100,142), Degree(20));
		createRamps(4, Vector3(253,99,56), Degree(180));
		///////////////////////////////////////////////////////////////////////////////////////
		
		Track->setNormaliseNormals(true);

	  mRoot->setFrameSmoothingPeriod(50);
}



//-------------------------------------------------------------------------------------
bool myApplication::frameStarted(const FrameEvent& evt)
{
    return OgreApplication::frameStarted(evt);
}

void viewPortOverlayListener::postViewportUpdate(const RenderTargetViewportEvent& evt)
{

	if(vWindow->getNumViewports() > 1) // IF SPLIT SCREEN
	{
		if(evt.source == vWindow->getViewport(LEFT_VIEWPORT)) // LEFT SIDE OF SCREEN
		{		
			//---SHOWN
			olayManager->getOverlayElement("TimerPanel")->show();
			olayManager->getOverlayElement("l_SpeedPanel")->show();
			olayManager->getOverlayElement("l_SpeedBarPanel")->show();
			//---HIDDEN
			olayManager->getOverlayElement("rightTimerPanel")->hide();
			olayManager->getOverlayElement("r_SpeedPanel")->hide();
			olayManager->getOverlayElement("r_SpeedBarPanel")->hide();
			olayManager->getOverlayElement("SpeedBarPanel")->hide();
			olayManager->getOverlayElement("SpeedPanel")->hide();
		}
		if(evt.source == vWindow->getViewport(RIGHT_VIEWPORT))// RIGHT SIDE OF SCREEN
		{
			//---SHOWN
			olayManager->getOverlayElement("rightTimerPanel")->show();
			olayManager->getOverlayElement("r_SpeedPanel")->show();
			olayManager->getOverlayElement("r_SpeedBarPanel")->show();
			//---HIDDEN
			olayManager->getOverlayElement("TimerPanel")->hide();		
			olayManager->getOverlayElement("l_SpeedPanel")->hide();
			olayManager->getOverlayElement("l_SpeedBarPanel")->hide();
			olayManager->getOverlayElement("SpeedBarPanel")->hide();
			olayManager->getOverlayElement("SpeedPanel")->hide();
		}
	}else{//ONE PLAYER SCREEN (FULL)
		//---SHOWN
		olayManager->getOverlayElement("TimerPanel")->show();
		olayManager->getOverlayElement("SpeedBarPanel")->show();
		olayManager->getOverlayElement("SpeedPanel")->show();
		//---HIDDEN
		olayManager->getOverlayElement("rightTimerPanel")->hide();
		olayManager->getOverlayElement("l_SpeedBarPanel")->hide();
		olayManager->getOverlayElement("r_SpeedBarPanel")->hide();
		olayManager->getOverlayElement("l_SpeedPanel")->hide();
		olayManager->getOverlayElement("r_SpeedPanel")->hide();
	}



}
void viewPortOverlayListener::preViewportUpdate(const RenderTargetViewportEvent& evt)
{
	
	//	if(vWindow->getNumViewports() > 1) // IF SPLIT SCREEN
	//{
	//	if(evt.source == vWindow->getViewport(LEFT_VIEWPORT)) // LEFT SIDE OF SCREEN
	//	{		
	//		//---SHOWN
	//		olayManager->getOverlayElement("TimerPanel")->show();
	//		olayManager->getOverlayElement("l_SpeedPanel")->show();
	//		olayManager->getOverlayElement("l_SpeedBarPanel")->show();
	//		//---HIDDEN
	//		olayManager->getOverlayElement("rightTimerPanel")->hide();
	//		olayManager->getOverlayElement("r_SpeedPanel")->hide();
	//		olayManager->getOverlayElement("r_SpeedBarPanel")->hide();
	//		olayManager->getOverlayElement("SpeedBarPanel")->hide();
	//		olayManager->getOverlayElement("SpeedPanel")->hide();
	//	}
	//	if(evt.source == vWindow->getViewport(RIGHT_VIEWPORT))// RIGHT SIDE OF SCREEN
	//	{
	//		//---SHOWN
	//		olayManager->getOverlayElement("rightTimerPanel")->show();
	//		olayManager->getOverlayElement("r_SpeedPanel")->show();
	//		olayManager->getOverlayElement("r_SpeedBarPanel")->show();
	//		//---HIDDEN
	//		olayManager->getOverlayElement("TimerPanel")->hide();		
	//		olayManager->getOverlayElement("l_SpeedPanel")->hide();
	//		olayManager->getOverlayElement("l_SpeedBarPanel")->hide();
	//		olayManager->getOverlayElement("SpeedBarPanel")->hide();
	//		olayManager->getOverlayElement("SpeedPanel")->hide();
	//	}
	//}else{//ONE PLAYER SCREEN (FULL)
	//	//---SHOWN
	//	olayManager->getOverlayElement("TimerPanel")->show();
	//	olayManager->getOverlayElement("SpeedBarPanel")->show();
	//	olayManager->getOverlayElement("SpeedPanel")->show();
	//	//---HIDDEN
	//	olayManager->getOverlayElement("rightTimerPanel")->hide();
	//	olayManager->getOverlayElement("l_SpeedBarPanel")->hide();
	//	olayManager->getOverlayElement("r_SpeedBarPanel")->hide();
	//	olayManager->getOverlayElement("l_SpeedPanel")->hide();
	//	olayManager->getOverlayElement("r_SpeedPanel")->hide();
	//}

}

//-------------------------------------------------------------------------------------
void myApplication::createSceneManager()
{
	primarySceneMgr = mRoot->createSceneManager(ST_EXTERIOR_REAL_FAR, "primary");
	introSceneMgr = mRoot->createSceneManager(ST_EXTERIOR_REAL_FAR, "secondary");
}



void myApplication::createCamera()
{
   primarySceneMgr->createCamera(PLAYER_1_CAM);
   primarySceneMgr->createCamera(PLAYER_2_CAM);
    introSceneMgr->createCamera("introCam");


}

void myApplication::createViewports()
{
	setupViewport(mWindow, primarySceneMgr);
}




#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
#define WIN32_LEAN_AND_MEAN
#include "windows.h"

#endif

#ifdef __cplusplus
extern "C" {
#endif

#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
#else
int main(int argc, char *argv[])
#endif
{
   // Create application object
   myApplication app;


   //SET_TERM_HANDLER;

   try
   {
      app.go();
   }
   catch( Ogre::Exception& e )
   {
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
      MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
#else
      std::cerr << "An exception has occured: " << e.getFullDescription().c_str() << std::endl;
#endif
   }

   return 0;
}

#ifdef __cplusplus
}
#endif